/**
 * List 集合类
 * Array 的扩展，可以支持lambda 查询
 */
export default class List<T> extends Array<T> {
  constructor(list?: Array<T>) {
    super();
    if (list != null && Array.isArray(list)) {
      list.forEach((element) => {
        this.push(element);
      });
    }
  }
  public clear() {
    this.splice(0, this.length);
  }
  /**数据更新-自定义扩展时使用 */
  public update() {}
  /**
   * where条件查询
   * @param compareFn 比较器
   */
  public where(compareFn: (t: T) => boolean): List<T> {
    var newArray = new List<T>();
    this.forEach((element) => {
      if (compareFn(element)) newArray.push(element);
    });
    return newArray;
  }

  /**
   * where条件查询-双数组查询
   * @param array 第二数组
   * @param compareFn 比较器
   */
  public wheres<R>(
    array: Array<R>,
    compareFn: (t: T, r: R) => boolean
  ): List<T> {
    var newArray = new List<T>();
    this.forEach((item) => {
      array.forEach((item2) => {
        if (compareFn(item, item2)) newArray.push(item);
      });
    });
    return newArray;
  }

  /**
   * 去重
   * @param array  去重数组
   * @param distinctFn  去重字段
   */
  public distinct(distinctFn: (t: T) => any): List<T> {
    var newArray = new List<T>();
    for (let i = 0; i < this.length; i++) {
      const item = this[i];
      var isok = false;
      for (let j = i + 1; j < this.length; j++) {
        const item2 = this[j];
        if (distinctFn(item) == distinctFn(item2)) {
          isok = true;
        }
      }
      if (!isok) {
        newArray.push(item);
      }
    }
    return newArray;
  }

  /**
   * 获取新查询结果集
   * @param array  去重数组
   * @param selectFn  去重字段
   */
  public select<R>(selectFn: (t: T) => R): List<R> {
    var newArray = new List<R>();
    for (let i = 0; i < this.length; i++) {
      newArray.push(selectFn(this[i]));
    }
    return newArray;
  }
  /**count 统计*/
  public count(compareFn: (t: T) => boolean): number {
    var count = 0;
    this.forEach((element) => {
      if (compareFn(element)) count++;
    });
    return count;
  }
  /**首条数据条件查询 */
  public first(compareFn?: (t: T) => boolean) {
    for (let i = 0; i < this.length - 1; i++) {
      const element = this[i];
      if (compareFn(element)) {
        return element;
      }
    }
    return null;
  }
}
